home *** CD-ROM | disk | FTP | other *** search
- *
- * $VER: log.s 33.1 (20.1.97)
- *
- * " computes the natural logarithm of a normalized input"
- *
- * Version history:
- *
- * 33.1 20.1.97 (c) Motorola
- *
- * - cut'n pasted from M68060SP
- *
- * 33.2 22.1.97 (c) Motorola
- *
- * - added log10 and log2
- * - log trashed a6, fixed
- *
-
- machine 68040
- fpu 1
-
- XDEF _log
- XDEF @log
- XDEF _log10
- XDEF @log10
- XDEF _log2
- XDEF @log2
-
- *************************************************************************
- * log(): computes the natural logarithm of a normalized input *
- * *
- * INPUT *************************************************************** *
- * fp0 = extended precision input *
- * *
- * OUTPUT ************************************************************** *
- * fp0 = log(X) *
- * *
- * ACCURACY and MONOTONICITY ******************************************* *
- * The returned result is within 2 ulps in 64 significant bit, *
- * i.e. within 0.5001 ulp to 53 bits if the result is subsequently *
- * rounded to double precision. The result is provably monotonic *
- * in double precision. *
- * *
- * ALGORITHM *********************************************************** *
- * LOGN: *
- * Step 1. If |X-1| < 1/16, approximate log(X) by an odd *
- * polynomial in u, where u = 2(X-1)/(X+1). Otherwise, *
- * move on to Step 2. *
- * *
- * Step 2. X = 2**k * Y where 1 <= Y < 2. Define F to be the first *
- * seven significant bits of Y plus 2**(-7), i.e. *
- * F = 1.xxxxxx1 in base 2 where the six "x" match those *
- * of Y. Note that |Y-F| <= 2**(-7). *
- * *
- * Step 3. Define u = (Y-F)/F. Approximate log(1+u) by a *
- * polynomial in u, log(1+u) = poly. *
- * *
- * Step 4. Reconstruct *
- * log(X) = log( 2**k * Y ) = k*log(2) + log(F) + log(1+u) *
- * by k*log(2) + (log(F) + poly). The values of log(F) are *
- * calculated beforehand and stored in the program. *
- * *
- * Implementation Notes: *
- * Note 1. There are 64 different possible values for F, thus 64 *
- * log(F)'s need to be tabulated. Moreover, the values of *
- * 1/F are also tabulated so that the division in (Y-F)/F *
- * can be performed by a multiplication. *
- * *
- * Note 2. To fully exploit the pipeline, polynomials are usually *
- * separated into two parts evaluated independently before *
- * being added up. *
- * *
- *************************************************************************
-
- cnop 0,4
-
- LOGOF2 dc.l $3FFE0000,$B17217F7,$D1CF79AC,$00000000
- one dc.l $3F800000
- zero dc.l $00000000
- infty dc.l $7F800000
- negone dc.l $BF800000
- LOGA6 dc.l $3FC2499A,$B5E4040B
- LOGA5 dc.l $BFC555B5,$848CB7DB
- LOGA4 dc.l $3FC99999,$987D8730
- LOGA3 dc.l $BFCFFFFF,$FF6F7E97
- LOGA2 dc.l $3FD55555,$555555A4
- LOGA1 dc.l $BFE00000,$00000008
- LOGB5 dc.l $3F175496,$ADD7DAD6
- LOGB4 dc.l $3F3C71C2,$FE80C7E0
- LOGB3 dc.l $3F624924,$928BCCFF
- LOGB2 dc.l $3F899999,$999995EC
- LOGB1 dc.l $3FB55555,$55555555
- TWO dc.l $40000000,$00000000
- LTHOLD dc.l $3f990000,$80000000,$00000000,$00000000
- LOGTBL dc.l $3FFE0000,$FE03F80F,$E03F80FE,$00000000
- dc.l $3FF70000,$FF015358,$833C47E2,$00000000
- dc.l $3FFE0000,$FA232CF2,$52138AC0,$00000000
- dc.l $3FF90000,$BDC8D83E,$AD88D549,$00000000
- dc.l $3FFE0000,$F6603D98,$0F6603DA,$00000000
- dc.l $3FFA0000,$9CF43DCF,$F5EAFD48,$00000000
- dc.l $3FFE0000,$F2B9D648,$0F2B9D65,$00000000
- dc.l $3FFA0000,$DA16EB88,$CB8DF614,$00000000
- dc.l $3FFE0000,$EF2EB71F,$C4345238,$00000000
- dc.l $3FFB0000,$8B29B775,$1BD70743,$00000000
- dc.l $3FFE0000,$EBBDB2A5,$C1619C8C,$00000000
- dc.l $3FFB0000,$A8D839F8,$30C1FB49,$00000000
- dc.l $3FFE0000,$E865AC7B,$7603A197,$00000000
- dc.l $3FFB0000,$C61A2EB1,$8CD907AD,$00000000
- dc.l $3FFE0000,$E525982A,$F70C880E,$00000000
- dc.l $3FFB0000,$E2F2A47A,$DE3A18AF,$00000000
- dc.l $3FFE0000,$E1FC780E,$1FC780E2,$00000000
- dc.l $3FFB0000,$FF64898E,$DF55D551,$00000000
- dc.l $3FFE0000,$DEE95C4C,$A037BA57,$00000000
- dc.l $3FFC0000,$8DB956A9,$7B3D0148,$00000000
- dc.l $3FFE0000,$DBEB61EE,$D19C5958,$00000000
- dc.l $3FFC0000,$9B8FE100,$F47BA1DE,$00000000
- dc.l $3FFE0000,$D901B203,$6406C80E,$00000000
- dc.l $3FFC0000,$A9372F1D,$0DA1BD17,$00000000
- dc.l $3FFE0000,$D62B80D6,$2B80D62C,$00000000
- dc.l $3FFC0000,$B6B07F38,$CE90E46B,$00000000
- dc.l $3FFE0000,$D3680D36,$80D3680D,$00000000
- dc.l $3FFC0000,$C3FD0329,$06488481,$00000000
- dc.l $3FFE0000,$D0B69FCB,$D2580D0B,$00000000
- dc.l $3FFC0000,$D11DE0FF,$15AB18CA,$00000000
- dc.l $3FFE0000,$CE168A77,$25080CE1,$00000000
- dc.l $3FFC0000,$DE1433A1,$6C66B150,$00000000
- dc.l $3FFE0000,$CB8727C0,$65C393E0,$00000000
- dc.l $3FFC0000,$EAE10B5A,$7DDC8ADD,$00000000
- dc.l $3FFE0000,$C907DA4E,$871146AD,$00000000
- dc.l $3FFC0000,$F7856E5E,$E2C9B291,$00000000
- dc.l $3FFE0000,$C6980C69,$80C6980C,$00000000
- dc.l $3FFD0000,$82012CA5,$A68206D7,$00000000
- dc.l $3FFE0000,$C4372F85,$5D824CA6,$00000000
- dc.l $3FFD0000,$882C5FCD,$7256A8C5,$00000000
- dc.l $3FFE0000,$C1E4BBD5,$95F6E947,$00000000
- dc.l $3FFD0000,$8E44C60B,$4CCFD7DE,$00000000
- dc.l $3FFE0000,$BFA02FE8,$0BFA02FF,$00000000
- dc.l $3FFD0000,$944AD09E,$F4351AF6,$00000000
- dc.l $3FFE0000,$BD691047,$07661AA3,$00000000
- dc.l $3FFD0000,$9A3EECD4,$C3EAA6B2,$00000000
- dc.l $3FFE0000,$BB3EE721,$A54D880C,$00000000
- dc.l $3FFD0000,$A0218434,$353F1DE8,$00000000
- dc.l $3FFE0000,$B92143FA,$36F5E02E,$00000000
- dc.l $3FFD0000,$A5F2FCAB,$BBC506DA,$00000000
- dc.l $3FFE0000,$B70FBB5A,$19BE3659,$00000000
- dc.l $3FFD0000,$ABB3B8BA,$2AD362A5,$00000000
- dc.l $3FFE0000,$B509E68A,$9B94821F,$00000000
- dc.l $3FFD0000,$B1641795,$CE3CA97B,$00000000
- dc.l $3FFE0000,$B30F6352,$8917C80B,$00000000
- dc.l $3FFD0000,$B7047551,$5D0F1C61,$00000000
- dc.l $3FFE0000,$B11FD3B8,$0B11FD3C,$00000000
- dc.l $3FFD0000,$BC952AFE,$EA3D13E1,$00000000
- dc.l $3FFE0000,$AF3ADDC6,$80AF3ADE,$00000000
- dc.l $3FFD0000,$C2168ED0,$F458BA4A,$00000000
- dc.l $3FFE0000,$AD602B58,$0AD602B6,$00000000
- dc.l $3FFD0000,$C788F439,$B3163BF1,$00000000
- dc.l $3FFE0000,$AB8F69E2,$8359CD11,$00000000
- dc.l $3FFD0000,$CCECAC08,$BF04565D,$00000000
- dc.l $3FFE0000,$A9C84A47,$A07F5638,$00000000
- dc.l $3FFD0000,$D2420487,$2DD85160,$00000000
- dc.l $3FFE0000,$A80A80A8,$0A80A80B,$00000000
- dc.l $3FFD0000,$D7894992,$3BC3588A,$00000000
- dc.l $3FFE0000,$A655C439,$2D7B73A8,$00000000
- dc.l $3FFD0000,$DCC2C4B4,$9887DACC,$00000000
- dc.l $3FFE0000,$A4A9CF1D,$96833751,$00000000
- dc.l $3FFD0000,$E1EEBD3E,$6D6A6B9E,$00000000
- dc.l $3FFE0000,$A3065E3F,$AE7CD0E0,$00000000
- dc.l $3FFD0000,$E70D785C,$2F9F5BDC,$00000000
- dc.l $3FFE0000,$A16B312E,$A8FC377D,$00000000
- dc.l $3FFD0000,$EC1F392C,$5179F283,$00000000
- dc.l $3FFE0000,$9FD809FD,$809FD80A,$00000000
- dc.l $3FFD0000,$F12440D3,$E36130E6,$00000000
- dc.l $3FFE0000,$9E4CAD23,$DD5F3A20,$00000000
- dc.l $3FFD0000,$F61CCE92,$346600BB,$00000000
- dc.l $3FFE0000,$9CC8E160,$C3FB19B9,$00000000
- dc.l $3FFD0000,$FB091FD3,$8145630A,$00000000
- dc.l $3FFE0000,$9B4C6F9E,$F03A3CAA,$00000000
- dc.l $3FFD0000,$FFE97042,$BFA4C2AD,$00000000
- dc.l $3FFE0000,$99D722DA,$BDE58F06,$00000000
- dc.l $3FFE0000,$825EFCED,$49369330,$00000000
- dc.l $3FFE0000,$9868C809,$868C8098,$00000000
- dc.l $3FFE0000,$84C37A7A,$B9A905C9,$00000000
- dc.l $3FFE0000,$97012E02,$5C04B809,$00000000
- dc.l $3FFE0000,$87224C2E,$8E645FB7,$00000000
- dc.l $3FFE0000,$95A02568,$095A0257,$00000000
- dc.l $3FFE0000,$897B8CAC,$9F7DE298,$00000000
- dc.l $3FFE0000,$94458094,$45809446,$00000000
- dc.l $3FFE0000,$8BCF55DE,$C4CD05FE,$00000000
- dc.l $3FFE0000,$92F11384,$0497889C,$00000000
- dc.l $3FFE0000,$8E1DC0FB,$89E125E5,$00000000
- dc.l $3FFE0000,$91A2B3C4,$D5E6F809,$00000000
- dc.l $3FFE0000,$9066E68C,$955B6C9B,$00000000
- dc.l $3FFE0000,$905A3863,$3E06C43B,$00000000
- dc.l $3FFE0000,$92AADE74,$C7BE59E0,$00000000
- dc.l $3FFE0000,$8F1779D9,$FDC3A219,$00000000
- dc.l $3FFE0000,$94E9BFF6,$15845643,$00000000
- dc.l $3FFE0000,$8DDA5202,$37694809,$00000000
- dc.l $3FFE0000,$9723A1B7,$20134203,$00000000
- dc.l $3FFE0000,$8CA29C04,$6514E023,$00000000
- dc.l $3FFE0000,$995899C8,$90EB8990,$00000000
- dc.l $3FFE0000,$8B70344A,$139BC75A,$00000000
- dc.l $3FFE0000,$9B88BDAA,$3A3DAE2F,$00000000
- dc.l $3FFE0000,$8A42F870,$5669DB46,$00000000
- dc.l $3FFE0000,$9DB4224F,$FFE1157C,$00000000
- dc.l $3FFE0000,$891AC73A,$E9819B50,$00000000
- dc.l $3FFE0000,$9FDADC26,$8B7A12DA,$00000000
- dc.l $3FFE0000,$87F78087,$F78087F8,$00000000
- dc.l $3FFE0000,$A1FCFF17,$CE733BD4,$00000000
- dc.l $3FFE0000,$86D90544,$7A34ACC6,$00000000
- dc.l $3FFE0000,$A41A9E8F,$5446FB9F,$00000000
- dc.l $3FFE0000,$85BF3761,$2CEE3C9B,$00000000
- dc.l $3FFE0000,$A633CD7E,$6771CD8B,$00000000
- dc.l $3FFE0000,$84A9F9C8,$084A9F9D,$00000000
- dc.l $3FFE0000,$A8489E60,$0B435A5E,$00000000
- dc.l $3FFE0000,$83993052,$3FBE3368,$00000000
- dc.l $3FFE0000,$AA59233C,$CCA4BD49,$00000000
- dc.l $3FFE0000,$828CBFBE,$B9A020A3,$00000000
- dc.l $3FFE0000,$AC656DAE,$6BCC4985,$00000000
- dc.l $3FFE0000,$81848DA8,$FAF0D277,$00000000
- dc.l $3FFE0000,$AE6D8EE3,$60BB2468,$00000000
- dc.l $3FFE0000,$80808080,$80808081,$00000000
- dc.l $3FFE0000,$B07197A2,$3C46C654,$00000000
-
-
- X EQU -12
- XDCARE EQU X+2
- XFRAC EQU X+4
- KLOG2 EQU -12
- SAVEU EQU -12
- F EQU -24
- FFRAC EQU F+4
- TEMP_SIZE EQU 24
-
- _log
- fmove.d (4,sp),fp0
- @log
- link a1,#-TEMP_SIZE
- fmove.x fp0,(X,a1)
-
- .LOGBGN
- ;--FPCR SAVED AND CLEARED, INPUT IS 2^(ADJK)*FP0, FP0 CONTAINS
- ;--A FINITE, NON-ZERO, NORMALIZED NUMBER.
-
- move.l (X,a1),d1
- move.w (X+4,a1),d1
-
- tst.l d1 ; CHECK IF X IS NEGATIVE
- ble.w .LOGNEG ; LOG OF NEGATIVE ARGUMENT IS INVALID
-
- ; X IS POSITIVE, CHECK IF X IS NEAR 1
-
- cmp.l #$3ffef07d,d1 ; IS X < 15/16?
- blt.b .LOGMAIN ; YES
- cmp.l #$3fff8841,d1 ; IS X > 17/16?
- ble.w .LOGNEAR1 ; NO
-
- .LOGMAIN
-
- ;--THIS SHOULD BE THE USUAL CASE, X NOT VERY CLOSE TO 1
-
- ;--X = 2^(K) * Y, 1 <= Y < 2. THUS, Y = 1.XXXXXXXX....XX IN BINARY.
- ;--WE DEFINE F = 1.XXXXXX1, I.E. FIRST 7 BITS OF Y AND ATTACH A 1.
- ;--THE IDEA IS THAT LOG(X) = K*LOG2 + LOG(Y)
- ;-- = K*LOG2 + LOG(F) + LOG(1 + (Y-F)/F).
- ;--NOTE THAT U = (Y-F)/F IS VERY SMALL AND THUS APPROXIMATING
- ;--LOG(1+U) CAN BE VERY EFFICIENT.
- ;--ALSO NOTE THAT THE VALUE 1/F IS STORED IN A TABLE SO THAT NO
- ;--DIVISION IS NEEDED TO CALCULATE (Y-F)/F.
-
- ;--GET K, Y, F, AND ADDRESS OF 1/F.
-
- asr.l #8,d1
- asr.l #8,d1 ; SHIFTED 16 BITS, BIASED EXPO. OF X
- sub.l #$3FFF,d1 ; THIS IS K
-
- lea (LOGTBL,pc),a0 ; BASE ADDRESS OF 1/F AND LOG(F)
- fmove.l d1,fp1 ; CONVERT K TO FLOATING-POINT FORMAT
-
- ;--WHILE THE CONVERSION IS GOING ON, WE GET F AND ADDRESS OF 1/F
- move.l #$3FFF0000,(X,a1) ; X IS NOW Y, I.E. 2^(-K)*X
- move.l (XFRAC,a1),(FFRAC,a1)
- and.l #$FE000000,(FFRAC,a1) ; FIRST 7 BITS OF Y
- or.l #$01000000,(FFRAC,a1)
- move.l (FFRAC,a1),d1
- and.l #$7E000000,d1
- asr.l #8,d1
- asr.l #8,d1
- asr.l #4,d1 ; SHIFTED 20, D0 IS THE DISPLACEMENT
- add.l d1,a0 ; A0 IS THE ADDRESS FOR 1/F
-
- fmove.x (X,a1),fp0
- move.l #$3fff0000,(F,a1)
- clr.l (F+8,a1)
- fsub.x (F,a1),fp0 ; Y-F
- fmovem.x fp2/fp3,-(sp) ; SAVE FP2-3 WHILE FP0 IS NOT READY
- ;--SUMMARY: FP0 IS Y-F, A0 IS ADDRESS OF 1/F, FP1 IS K
- ;--REGISTERS SAVED: FPCR, FP1, FP2
-
- .LP1CONT1
- ;--AN RE-ENTRY POINT FOR LOGNP1
- fmul.x (a0),fp0 ; FP0 IS U = (Y-F)/F
- fmul.x (LOGOF2,pc),fp1 ; GET K*LOG2 WHILE FP0 IS NOT READY
- fmove.x fp0,fp2
- fmul.x fp2,fp2 ; FP2 IS V=U*U
- fmove.x fp1,(KLOG2,a1) ; PUT K*LOG2 IN MEMEORY, FREE FP1
-
- ;--LOG(1+U) IS APPROXIMATED BY
- ;--U + V*(A1+U*(A2+U*(A3+U*(A4+U*(A5+U*A6))))) WHICH IS
- ;--[U + V*(A1+V*(A3+V*A5))] + [U*V*(A2+V*(A4+V*A6))]
-
- fmove.x fp2,fp3
- fmove.x fp2,fp1
-
- fmul.d (LOGA6,pc),fp1 ; V*A6
- fmul.d (LOGA5,pc),fp2 ; V*A5
-
- fadd.d (LOGA4,pc),fp1 ; A4+V*A6
- fadd.d (LOGA3,pc),fp2 ; A3+V*A5
-
- fmul.x fp3,fp1 ; V*(A4+V*A6)
- fmul.x fp3,fp2 ; V*(A3+V*A5)
-
- fadd.d (LOGA2,pc),fp1 ; A2+V*(A4+V*A6)
- fadd.d (LOGA1,pc),fp2 ; A1+V*(A3+V*A5)
-
- fmul.x fp3,fp1 ; V*(A2+V*(A4+V*A6))
- addq.l #8,a0 ; ADDRESS OF LOG(F)
- fmul.x fp3,fp2 ; V*(A1+V*(A3+V*A5))
- addq.l #8,a0
- fmul.x fp0,fp1 ; U*V*(A2+V*(A4+V*A6))
- fadd.x fp2,fp0 ; U+V*(A1+V*(A3+V*A5))
-
- fadd.x (a0),fp1 ; LOG(F)+U*V*(A2+V*(A4+V*A6))
- fmovem.x (sp)+,fp2/fp3 ; RESTORE FP2-3
- fadd.x fp1,fp0 ; FP0 IS LOG(F) + LOG(1+U)
-
- fadd.x (KLOG2,a1),fp0 ; FINAL ADD
- unlk a1
- rts
-
- .LOGNEAR1
-
- ; if the input is exactly equal to one, then exit through ld_pzero.
- ; if these 2 lines weren't here, the correct answer would be returned
- ; but the INEX2 bit would be set.
-
- fcmp.s #1,fp0 ; is it equal to one?
- fbeq .pzero ; yes
-
- ;--REGISTERS SAVED: FPCR, FP1. FP0 CONTAINS THE INPUT.
- fmove.x fp0,fp1
- fsub.s (one,pc),fp1 ; FP1 IS X-1
- fadd.s (one,pc),fp0 ; FP0 IS X+1
- fadd.x fp1,fp1 ; FP1 IS 2(X-1)
- ;--LOG(X) = LOG(1+U/2)-LOG(1-U/2) WHICH IS AN ODD POLYNOMIAL
- ;--IN U, U = 2(X-1)/(X+1) = FP1/FP0
-
- .LP1CONT2
- ;--THIS IS AN RE-ENTRY POINT FOR LOGNP1
- fdiv.x fp0,fp1 ; FP1 IS U
- fmovem.x fp2/fp3,-(sp) ; SAVE FP2-3
-
- ;--REGISTERS SAVED ARE NOW FPCR,FP1,FP2,FP3
- ;--LET V=U*U, W=V*V, CALCULATE
- ;--U + U*V*(B1 + V*(B2 + V*(B3 + V*(B4 + V*B5)))) BY
- ;--U + U*V*( [B1 + W*(B3 + W*B5)] + [V*(B2 + W*B4)] )
-
- fmove.x fp1,fp0
- fmul.x fp0,fp0 ; FP0 IS V
- fmove.x fp1,(SAVEU,a1) ; STORE U IN MEMORY, FREE FP1
- fmove.x fp0,fp1
- fmul.x fp1,fp1 ; FP1 IS W
-
- fmove.d (LOGB5,pc),fp3
- fmove.d (LOGB4,pc),fp2
-
- fmul.x fp1,fp3 ; W*B5
- fmul.x fp1,fp2 ; W*B4
-
- fadd.d (LOGB3,pc),fp3 ; B3+W*B5
- fadd.d (LOGB2,pc),fp2 ; B2+W*B4
-
- fmul.x fp3,fp1 ; W*(B3+W*B5), FP3 RELEASED
-
- fmul.x fp0,fp2 ; V*(B2+W*B4)
-
- fadd.d (LOGB1,pc),fp1 ; B1+W*(B3+W*B5)
- fmul.x (SAVEU,a1),fp0 ; FP0 IS U*V
-
- fadd.x fp2,fp1 ; B1+W*(B3+W*B5) + V*(B2+W*B4), FP2 RELEASED
- fmovem.x (sp)+,fp2/fp3 ; FP2-3 RESTORED
-
- fmul.x fp1,fp0 ; U*V*( [B1+W*(B3+W*B5)] + [V*(B2+W*B4)] )
-
- fadd.x (SAVEU,a1),fp0
- unlk a1
- rts
-
- ;--REGISTERS SAVED FPCR. LOG(-VE) IS INVALID
- .pzero
- fmove.s #0,fp0
- .LOGNEG
- unlk a1
- rts
-
- *************************************************************************
- * log10(): computes the base-10 logarithm of a normalized input *
- * log2(): computes the base-2 logarithm of a normalized input *
- * *
- * INPUT *************************************************************** *
- * fp0 = extended precision input *
- * *
- * OUTPUT ************************************************************** *
- * fp0 = log10(X) or log2(X) *
- * *
- * ACCURACY and MONOTONICITY ******************************************* *
- * The returned result is within 1.7 ulps in 64 significant bit, *
- * i.e. within 0.5003 ulp to 53 bits if the result is subsequently *
- * rounded to double precision. The result is provably monotonic *
- * in double precision. *
- * *
- * ALGORITHM *********************************************************** *
- * *
- * log10: *
- * *
- * Step 0. If X < 0, create a NaN and raise the invalid operation *
- * flag. Otherwise, save FPCR in D1; set FpCR to default. *
- * Notes: Default means round-to-nearest mode, no floating-point *
- * traps, and precision control = double extended. *
- * *
- * Step 1. Call sLogN to obtain Y = log(X), the natural log of X. *
- * *
- * Step 2. Compute log_10(X) = log(X) * (1/log(10)). *
- * 2.1 Restore the user FPCR *
- * 2.2 Return ans := Y * INV_L10. *
- * *
- * log2: *
- * *
- * Step 0. If X < 0, create a NaN and raise the invalid operation *
- * flag. Otherwise, save FPCR in D1; set FpCR to default. *
- * Notes: Default means round-to-nearest mode, no floating-point *
- * traps, and precision control = double extended. *
- * *
- * Step 1. If X is not an integer power of two, i.e., X != 2^k, *
- * go to Step 3. *
- * *
- * Step 2. Return k. *
- * 2.1 Get integer k, X = 2^k. *
- * 2.2 Restore the user FPCR. *
- * 2.3 Return ans := convert-to-double-extended(k). *
- * *
- * Step 3. Call sLogN to obtain Y = log(X), the natural log of X. *
- * *
- * Step 4. Compute log_2(X) = log(X) * (1/log(2)). *
- * 4.1 Restore the user FPCR *
- * 4.2 Return ans := Y * INV_L2. *
- * *
- *************************************************************************
-
- cnop 0,8
-
- INV_L10 dc.l $3FFD0000,$DE5BD8A9,$37287195,$00000000
-
- INV_L2 dc.l $3FFF0000,$B8AA3B29,$5C17F0BC,$00000000
-
- *--entry point for log10(X), X is normalized
- _log10
- fmove.d (4,sp),fp0
- @log10
- fmove.s fp0,-(sp)
-
- tst.l (sp)
- blt.s .invalid
-
- fcmp.s #1,fp0
- fbeq .zero
-
- addq.l #4,sp
-
- bsr.w @log ; log(X), X normal.
-
- fmul.x (INV_L10,pc),fp0
- rts
- .zero fmove.s #0,fp0
- .invalid
- addq.l #4,sp
- rts
-
- ;--entry point for Log2(X), X is normalized
- _log2
- fmove.d (4,sp),fp0
- @log2
- fmove.x fp0,-(sp)
-
- tst.l (sp)
- blt.s .invalid
-
- tst.l (8,sp)
- bne .continue
-
- move.l (4,sp),d1
- and.l #$7FFFFFFF,d1
- bne.b .continue ; X is not 2^k
-
- ;--X = 2^k.
- move.w (sp),d1
- and.l #$00007FFF,d1
- lea (12,sp),sp
- sub.l #$3FFF,d1
- beq.l .zero
- fmove.l d1,fp0
- rts
- .zero
- fmove.s #0,fp0
- rts
-
- .continue:
- bsr @log ; log(X), X normal.
- fmul.x (INV_L2,pc),fp0
- .invalid
- lea (12,sp),sp
- rts
-